OAuth2Provider = require('oauth2-provider').OAuth2Provider
config = require __basename + '/config/config'
mysql = require __basename + '/connect/mysql/baby'
mohair = require 'mohair'
async = require 'async'
_ = require 'underscore'
makeExtraData = require __basename + '/helpers/oauth/extra_data'

module.exports = oauth = new OAuth2Provider
  crypt_key: config.oauth.cryptKey
  sign_key: config.oauth.signKey

#
# Check login status of the user, otherwise redirect user to login page with the authorizeUrl
#

oauth.on 'enforce_login', (req, res, authorizeUrl, next) ->
  return next req.session.userId if req.session.userId
  res.redirect '/oauth/login?next=' + encodeURIComponent authorizeUrl

#
# Authorize user whether have permission to enter the product
#

oauth.on 'authorize_form', (req, res, clientId, authorizeUrl) ->
  async.auto
    permission: (fn) ->
      mohair
        .connect(mysql)
        .table('users urr')
        .join('left join user_lv r on urr.lv_id = r.member_lv_id')
        .where('urr.user_id': req.session.userId)
        .where('r.product_id': clientId)
        .exists fn
    client: (fn) ->
      mohair
        .connect(mysql)
        .table('clients')
        .where(id: clientId)
        .findOne fn
  ,
    (err, results) ->
      res.locals.clientName = results.client.name
      res.locals.authorizeUrl = authorizeUrl
      if results.permission
        res.render 'oauth/authorize_success.hbs'
      else
        res.render 'oauth/authorize_fail.hbs'

#
# Add the extra value into access token
#

oauth.on 'create_access_token', (userId, clientId, next) ->
  makeExtraData userId, clientId, (err, result) ->
    next result

#
# Save the access_token
#

oauth.on 'save_access_token', (userId, clientId, accessToken) ->


#
# Pass in a valid access token, get the user info
#

oauth.on 'access_token', (req, info, next) ->
  if info.grant_date.getTime() + config.oauth.accessTokenTTL > Date.now()
    req.session.userId = info.user_id
    req.session.clientId = info.client_id
    req.session.groupId = info.extra_data?.groupId
    async.auto
      role: (callback) ->
        mohair
          .connect(mysql)
          .table('users urr')
          .join('left join user_lv r on urr.lv_id = r.member_lv_id')
          .select('urr.lv_id as role_id')
          .where('urr.user_id': info.user_id)
          .where('r.product_id': info.client_id)
          .findOne callback
      permission: ['role', (callback, results) ->
        return callback null, [] unless results.role
        return callback null, results.role
      ]
    ,
      (err, results) ->
        next err if err
        req.session.permissions = _.pluck results.permission, 'role_id'
        next()
  else
    req.session.error = 'access_token timeout'
    next()
